package splash.gui;

import splash.core.Util;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
import splash.core.security.*;
import java.io.*;
import javax.swing.JOptionPane;

public class Users extends javax.swing.JFrame {

    /** Creates new form Users */
    public Users(MainFrame mf) {
        this.mf = mf;
        initComponents();
    }

    private UserList usrl;
    private MainFrame mf;

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents()
    {
        jTextField1 = new javax.swing.JTextField();
        jPasswordField1 = new javax.swing.JPasswordField();
        jButton1 = new javax.swing.JButton();
        jComboBox1 = new javax.swing.JComboBox();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        addWindowListener(new java.awt.event.WindowAdapter()
        {
            public void windowOpened(java.awt.event.WindowEvent evt)
            {
                start(evt);
            }
        });

        jButton1.setText("Dodaj uporabnika");
        jButton1.addMouseListener(new java.awt.event.MouseAdapter()
        {
            public void mouseClicked(java.awt.event.MouseEvent evt)
            {
                jButton1MouseClicked(evt);
            }
        });

        jComboBox1.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                jComboBox1ActionPerformed(evt);
            }
        });

        jButton2.setText("Odstrani uporabnika");
        jButton2.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                jButton2ActionPerformed(evt);
            }
        });

        jButton3.setText("Zapri");
        jButton3.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                jButton3ActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(213, 213, 213)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jTextField1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 187, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jPasswordField1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 187, Short.MAX_VALUE))
                .add(219, 219, 219))
            .add(layout.createSequentialGroup()
                .add(232, 232, 232)
                .add(jButton1)
                .addContainerGap(241, Short.MAX_VALUE))
            .add(layout.createSequentialGroup()
                .add(205, 205, 205)
                .add(jComboBox1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 208, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(206, Short.MAX_VALUE))
            .add(layout.createSequentialGroup()
                .add(227, 227, 227)
                .add(jButton2)
                .addContainerGap(229, Short.MAX_VALUE))
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .addContainerGap(188, Short.MAX_VALUE)
                .add(jButton3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 255, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(176, 176, 176))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(27, 27, 27)
                .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(9, 9, 9)
                .add(jPasswordField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jButton1)
                .add(18, 18, 18)
                .add(jComboBox1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jButton2)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 113, Short.MAX_VALUE)
                .add(jButton3)
                .add(40, 40, 40))
        );
        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jComboBox1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBox1ActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_jComboBox1ActionPerformed

    private void start(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_start
        nalozi();
    }//GEN-LAST:event_start

    private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton1MouseClicked

        String username = jTextField1.getText();
        String pwd = new String(jPasswordField1.getPassword());

        if(Util.passwordStrength(pwd) < 5)
        {
             JOptionPane.showMessageDialog(this,
                    "Geslo je pre�ibko.", "", JOptionPane.ERROR_MESSAGE);
            return;
        }

        String password = Util.md5(pwd);

        if(username.matches("[><&\"]"))
        {
            /* XML injection? */
            JOptionPane.showMessageDialog(this,
                    "Uporabljate prepovedane znake - <>&\"", "", JOptionPane.ERROR_MESSAGE);
            return;
        }


        if(this.usrl == null)
            return;

        UserList ul = this.usrl;

        ul.add(new User(username, password, true));

        /* Izpisi v tabelo */
        try
        {
            izpisi(ul);
        }
        catch(Exception e)
        {
            /* Ne morem zapisati uporabnikov */
            JOptionPane.showMessageDialog(this,
                    "Napaka pri zapisovanju v datoteko\"users.xml\"", "", JOptionPane.ERROR_MESSAGE);
            return;
        }

        /* Nalo�i znova */
        nalozi();
        JOptionPane.showMessageDialog(this,
                    "Uporabnik uspe�no dodan", "", JOptionPane.INFORMATION_MESSAGE);
        jTextField1.setText("");
        jPasswordField1.setText("");

    }//GEN-LAST:event_jButton1MouseClicked

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed

        /* Selected user */
        int index = jComboBox1.getSelectedIndex();
        this.usrl.remove(index);

        try
        {
            izpisi(this.usrl);
        }
        catch(Exception e)
        {
            JOptionPane.showMessageDialog(this,
                    "Napaka pri zapisovanju v datoteko\"users.xml\"", "", JOptionPane.ERROR_MESSAGE);
        }
        nalozi();
        JOptionPane.showMessageDialog(this,
                    "Uporabnik uspe�no odstranjen.", "", JOptionPane.INFORMATION_MESSAGE);

    }//GEN-LAST:event_jButton2ActionPerformed

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
        if(this.mf == null)
            return;

        this.mf.closeUserForm();
    }//GEN-LAST:event_jButton3ActionPerformed

    public static void izpisi(UserList lst) throws Exception
    {

	/* Ustvarimo nov dokument */

	DocumentBuilderFactory factory
          = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        DOMImplementation impl = builder.getDOMImplementation();

        Document doc = impl.createDocument(null,null,null);

	Element users = doc.createElement("users");
	doc.appendChild(users);

	Element user, name, pass, restriction;
	User u;
	RestrictionSet rs;
	Restriction res;
	for(int i = 0; i < lst.size(); i++)
	{
	    u = lst.get(i);
	    rs = u.getRestrictions();

	    user = doc.createElement("user");
	    users.appendChild(user);

	    name = doc.createElement("ime");
	    name.setTextContent(u.getUsername());
	    user.appendChild(name);

	    pass = doc.createElement("geslo");
	    pass.setTextContent(u.getPassword());
	    user.appendChild(pass);

            if(rs == null)
                continue;
            
	    for(int j = 0; j < rs.size(); j++)
	    {
		res = rs.get(j);
		char z = getRestrictionChar(res.getType());
		if(z == 0)
		    continue;

		restriction = doc.createElement("omejitev");
		restriction.setTextContent(z + ":" + res.getDesc());
		user.appendChild(restriction);
	    }
	}

	/* Writeh to fileh */
	Source src = new DOMSource(doc);
	Result result = new StreamResult(new File("users.xml"));
        Transformer xformer = TransformerFactory.newInstance().newTransformer();
        xformer.setOutputProperty(OutputKeys.METHOD, "xml");
        xformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
        xformer.setOutputProperty
            ("{http://xml.apache.org/xslt}indent-amount", "4");
        xformer.setOutputProperty(OutputKeys.INDENT, "yes");
	xformer.transform(src, result);

    }

    private static char getRestrictionChar(RestrictionType t)
    {
	if(t.equals(RestrictionType.ADDONS))
	    return 'a';
	else if(t.equals(RestrictionType.READ))
	    return 'r';
	else if(t.equals(RestrictionType.WRITE))
	    return 'w';
	else if(t.equals(RestrictionType.EXECUTE))
	    return 'x';
	else if(t.equals(RestrictionType.SCREEN))
	    return 's';
	else if(t.equals(RestrictionType.DELETE))
	    return 'd';
	else if(t.equals(RestrictionType.SHUTDOWN))
	    return 'u';
	if(t.equals(RestrictionType.MESSAGE))
	    return 'i';
	else return 0;
    }

    private void nalozi()
    {
        UserList ul = null;
        jComboBox1.removeAllItems();
        try
        {
            ul = UserLoader.loadUsers("users.xml");
        }
        catch(Exception e)
        {
            /* Ne morem nalo�iti uporabnikov */
        }

        this.usrl = ul;

        for(int i = 0; i < ul.size(); i++)
            jComboBox1.addItem(ul.get(i).getUsername());
    }

    /**
    * @param args the command line arguments
    */
   /* public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Users().setVisible(true);
            }
        });
    }*/

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JComboBox jComboBox1;
    private javax.swing.JPasswordField jPasswordField1;
    private javax.swing.JTextField jTextField1;
    // End of variables declaration//GEN-END:variables

}
